package com.myres.dao;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.myres.model.Product;

public class ProductDao extends HibernateDaoSupport {

	public Product get(int id) {
		return getHibernateTemplate().get(Product.class, id);
	}

	public int save(Product product) {
		getHibernateTemplate().save(product);
		return product.getId();
	}

	public int update(Product product) {
		getHibernateTemplate().update(product);
		return product.getId();
	}

	public void delete(Product product) {
		getHibernateTemplate().delete(product);
	}

	public void delete(int id) {
		delete(get(id));
	}

	@SuppressWarnings("unchecked")
	public List<Product> findByName(String name) {
		String hql = "from Product p where p.name like '%" + name + "%'";
		return (List<Product>) getHibernateTemplate().find(hql);
	}

	@SuppressWarnings("unchecked")
	public List<Product> findAll() {
		String hql = "from Product";
		return (List<Product>) getHibernateTemplate().find(hql);
	}

	public List<Product> findAllOnIndex() {
		String hql = "from Product p where p.onIndex=1";
		return (List<Product>) getHibernateTemplate().find(hql);
	}

	public List<Product> findAllOnPromotion() {
		String hql = "from Product p where p.onPromotion=1";
		return (List<Product>) getHibernateTemplate().find(hql);
	}

	public List<Product> findAllOnRecommend() {
		String hql = "from Product p where p.onRecommend=1";
		return (List<Product>) getHibernateTemplate().find(hql);
	}

	private List<Product> getProductsInRangeWithHql(final Integer startWith,
			final Integer size, final String hql) {
		List<Product> resultList = getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						List<Product> result = session.createQuery(hql)
								.setFirstResult(startWith).setMaxResults(size)
								.list();
						return result;
					}

				});
		return resultList;
	}

	/**
	 * 
	 * @param startWith
	 *            keep null if you don't want to use in range function.
	 * @param size
	 *            same as above.
	 * @return
	 */
	public List<Product> findAllOrderByPriceInRange(Integer startWith,
			Integer size) {
		String hql = "from Product p order by p.price";
		if (startWith == null || size == null) {
			return (List<Product>) getHibernateTemplate().find(hql);
		} else {
			return getProductsInRangeWithHql(startWith, size, hql);
		}
	}

	/**
	 * 
	 * @param startWith
	 *            keep null if you don't want to use in range function.
	 * @param size
	 *            same as above.
	 * @return
	 */
	public List<Product> findAllOrderByScoreInRange(Integer startWith,
			Integer size) {
		String hql = "from Product p order by p.score";
		if (startWith == null || size == null) {
			return (List<Product>) getHibernateTemplate().find(hql);
		} else {
			return getProductsInRangeWithHql(startWith, size, hql);
		}
	}

	/**
	 * 
	 * @param name
	 * @param startWith
	 *            keep null if you don't want to use in range function.
	 * @param size
	 *            same as above.
	 * @return
	 */
	public List<Product> findbyNameOrderByPriceInRange(String name,
			Integer startWith, Integer size) {
		String hql = "from Product p where p.name like '%" + name
				+ "% order by p.price'";
		if (startWith == null || size == null) {
			return (List<Product>) getHibernateTemplate().find(hql);
		} else {
			return getProductsInRangeWithHql(startWith, size, hql);
		}
	}

	public List<Product> findbyNameOrderByScoreInRange(String name,
			Integer startWith, Integer size) {
		String hql = "from Product p where p.name like '%" + name
				+ "% order by p.score'";
		if (startWith == null || size == null) {
			return (List<Product>) getHibernateTemplate().find(hql);
		} else {
			return getProductsInRangeWithHql(startWith, size, hql);
		}
	}
}
